// Filename: errno.rs

/*
 * Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
 * OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
 * You can use this software according to the terms and conditions of the Mulan PSL v1.
 * You may obtain a copy of Mulan PSL v1 at:
 *   http://license.coscl.org.cn/MulanPSL
 *   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 *   PURPOSE.
 *   See the Mulan PSL v1 for more details.
 */

#![allow(non_upper_case_globals)]

pub const EPERM: i32 = 1; /* Operation not permitted */
pub const EAGAIN: i32 = 2; /* Try again */
pub const ENOMEM: i32 = 3; /* Out of memory */
pub const EACCES: i32 = 4; /* Permission denied */
pub const EINVAL: i32 = 5; /* Invalid argument */
pub const EFBIG: i32 = 6; /* File too large */
pub const ENOSPC: i32 = 7; /* No space left on device */
pub const ENOSYS: i32 = 8; /* Function not implemented */
pub const ENODATA: i32 = 9; /* No data available */
pub const ETIME: i32 = 10; /* Timer expired */
pub const ECAPBILITY: i32 = 11; /* Invalid capability */
pub const ESUPPORT: i32 = 12; /* Not supported */
pub const EBADSYSCALL: i32 = 13; /* Bad syscall number */
pub const ENOMAPPING: i32 = 14; /* Bad syscall number */
pub const ENOENT: i32 = 15; /* Entry does not exist */
pub const EEXIST: i32 = 16; /* Entry already exists */
pub const ENOTEMPTY: i32 = 17; /* Dir is not empty */
pub const ENOTDIR: i32 = 18; /* Does not refer to a directory */
pub const EFAULT: i32 = 19; /* Bad address */
pub const EBUSY: i32 = 20;

pub const EMAX: i32 = 21;

pub fn ERR_PTR(x: isize) -> *const () {
    x as *const ()
}

pub fn PTR_ERR(x: *const ()) -> isize {
    x as isize
}

pub fn IS_ERR(x: *const ()) -> bool {
    (x as isize) < 0 && (x as isize) > (-EMAX).try_into().unwrap()
}

#[cfg(test)]
mod tests {
    // Import the original code and test functions
    use super::*;

    // Test for ERR_PTR, PTR_ERR, and IS_ERR functions
    #[test]
    fn test_error_pointer_functions() {
        // Example values for testing
        let error_value: isize = -20; // Set to a value less than -EMAX
        let non_error_value: isize = 42;

        // Test ERR_PTR and PTR_ERR
        let error_ptr = ERR_PTR(error_value);
        assert_eq!(PTR_ERR(error_ptr), error_value);

        // Test IS_ERR
        assert!(IS_ERR(error_ptr));
        assert!(!IS_ERR(non_error_value as *const ()));
    }

    // Test constants
    #[test]
    fn test_error_constants() {
        assert_eq!(EPERM, 1);
        assert_eq!(EAGAIN, 2);
        assert_eq!(ENOMEM, 3);
        assert_eq!(EACCES, 4);
        assert_eq!(EINVAL, 5);
        assert_eq!(EFBIG, 6);
        assert_eq!(ENOSPC, 7);
        assert_eq!(ENOSYS, 8);
        assert_eq!(ENODATA, 9);
        assert_eq!(ETIME, 10);
        assert_eq!(ECAPBILITY, 11);
        assert_eq!(ESUPPORT, 12);
        assert_eq!(EBADSYSCALL, 13);
        assert_eq!(ENOMAPPING, 14);
        assert_eq!(ENOENT, 15);
        assert_eq!(EEXIST, 16);
        assert_eq!(ENOTEMPTY, 17);
        assert_eq!(ENOTDIR, 18);
        assert_eq!(EFAULT, 19);
        assert_eq!(EBUSY, 20);
        assert_eq!(EMAX, 21);
    }
}
